#include <linux/init.h>
#include <linux/of/early.h>
#include <linux/of/fdt.h>
#include <linux/memblock.h>

#include "of_private.h"

void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
{
	return memblock_alloc_or_panic(size, align);
}

/**
 * __unflatten_device_tree - create tree of device_nodes from flat blob
 * @blob: The blob to expand
 * @dad: Parent device node
 * @mynodes: The device_node tree created by the call
 * @dt_alloc: An allocator that provides a virtual address to memory
 * for the resulting tree
 * @detached: if true set OF_DETACHED on @mynodes
 *
 * unflattens a device-tree, creating the tree of struct device_node. It also
 * fills the "name" and "type" pointers of the nodes so the normal device-tree
 * walking functions can be used.
 *
 * Return: NULL on failure or the memory chunk containing the unflattened
 * device tree on success.
 */
void *__unflatten_device_tree(const void *blob,
                              struct device_node *dad,
                              struct device_node **mynodes,
                              void *(*dt_alloc)(u64 size, u64 align),
                              bool detached)
{
    void *mem;

    return mem;
}

/**
 * unflatten_device_tree - create tree of device_nodes from flat blob
 *
 * unflattens the device-tree passed by the firmware, creating the
 * tree of struct device_node. It also fills the "name" and "type"
 * pointers of the nodes so the normal device-tree walking functions
 * can be used.
 */
void __init unflatten_device_tree(void)
{
    void *fdt = initial_boot_params;

    /* Save the statically-placed regions in the reserved_mem array */
    fdt_scan_reserved_mem_reg_nodes();
#if 0//todo
    /* Populate an empty root node when bootloader doesn't provide one */
    if (!fdt)
    {
        fdt = (void *)__dtb_empty_root_begin;
        /* fdt_totalsize() will be used for copy size */
        if (fdt_totalsize(fdt) >
            __dtb_empty_root_end - __dtb_empty_root_begin)
        {
            pr_err("invalid size in dtb_empty_root\n");
            return;
        }
        of_fdt_crc32 = crc32_be(~0, fdt, fdt_totalsize(fdt));
        fdt = copy_device_tree(fdt);
    }
#endif
    __unflatten_device_tree(fdt, NULL, &of_root,
                            early_init_dt_alloc_memory_arch, false);

    /* Get pointer to "/chosen" and "/aliases" nodes for use everywhere */
    of_alias_scan(early_init_dt_alloc_memory_arch);
}
